#include <iostream>
#include <boost/asio.hpp>
#include <string>

using boost::asio::ip::tcp;

// TCP 客户端示例
// 演示如何创建简单的 TCP 客户端连接

class TcpClient {
private:
    boost::asio::io_context& io_context_;
    tcp::socket socket_;

public:
    TcpClient(boost::asio::io_context& io_context)
        : io_context_(io_context), socket_(io_context) {}

    void connect(const std::string& host, const std::string& port) {
        tcp::resolver resolver(io_context_);
        auto endpoints = resolver.resolve(host, port);

        boost::asio::connect(socket_, endpoints);
        std::cout << "Connected to " << host << ":" << port << std::endl;
    }

    void send_message(const std::string& message) {
        boost::asio::write(socket_, boost::asio::buffer(message + "\n"));
        std::cout << "Sent: " << message << std::endl;
    }

    std::string receive_message() {
        boost::asio::streambuf buffer;
        boost::asio::read_until(socket_, buffer, "\n");

        std::istream is(&buffer);
        std::string message;
        std::getline(is, message);

        std::cout << "Received: " << message << std::endl;
        return message;
    }

    void close() {
        socket_.close();
        std::cout << "Connection closed." << std::endl;
    }
};

// 简单的 HTTP 客户端示例
void http_client_example() {
    try {
        boost::asio::io_context io_context;

        // 解析主机名和服务
        tcp::resolver resolver(io_context);
        auto endpoints = resolver.resolve("httpbin.org", "80");

        // 创建并连接 socket
        tcp::socket socket(io_context);
        boost::asio::connect(socket, endpoints);

        // 发送 HTTP GET 请求
        std::string request =
            "GET /get HTTP/1.1\r\n"
            "Host: httpbin.org\r\n"
            "Connection: close\r\n\r\n";

        boost::asio::write(socket, boost::asio::buffer(request));
        std::cout << "HTTP request sent." << std::endl;

        // 读取响应
        boost::asio::streambuf response;
        boost::system::error_code error;

        while (boost::asio::read(socket, response,
                boost::asio::transfer_at_least(1), error)) {
            if (error == boost::asio::error::eof) {
                break; // 连接正常关闭
            } else if (error) {
                throw boost::system::system_error(error);
            }
        }

        // 输出响应
        std::cout << "\nHTTP Response:\n";
        std::cout << &response << std::endl;

    } catch (std::exception& e) {
        std::cerr << "HTTP client error: " << e.what() << std::endl;
    }
}

// 本地回环测试客户端
void local_client_example() {
    try {
        boost::asio::io_context io_context;
        TcpClient client(io_context);

        std::cout << "\n=== Local TCP Client Example ===" << std::endl;
        std::cout << "Note: This example requires a server running on localhost:12345" << std::endl;
        std::cout << "You can test with: nc -l 12345" << std::endl;

        // 尝试连接到本地服务器
        try {
            client.connect("127.0.0.1", "12345");

            // 发送一些消息
            client.send_message("Hello from Boost.Asio client!");
            client.send_message("This is a test message.");

            // 接收响应（如果服务器发送了响应）
            // client.receive_message();

            client.close();

        } catch (const std::exception& e) {
            std::cout << "Could not connect to local server: " << e.what() << std::endl;
            std::cout << "This is expected if no server is running." << std::endl;
        }

    } catch (std::exception& e) {
        std::cerr << "Local client error: " << e.what() << std::endl;
    }
}

int main() {
    std::cout << "=== Boost.Asio TCP Client Examples ===" << std::endl;

    // 示例1: HTTP 客户端
    std::cout << "\n1. HTTP Client Example:" << std::endl;
    http_client_example();

    // 示例2: 本地 TCP 客户端
    local_client_example();

    return 0;
}
